package cn.iocoder.yudao.module.infra.service.clouddisk.impl;

import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.ServiceException;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.api.deduplication.DeduplicationFileApi;
import cn.iocoder.yudao.module.infra.api.deduplication.dto.DeduplicationFileRespDTO;
import cn.iocoder.yudao.module.infra.controller.app.clouddisk.vo.*;
import cn.iocoder.yudao.module.infra.dal.dataobject.clouddisk.UserCloudDiskDO;
import cn.iocoder.yudao.module.infra.dal.mysql.clouddisk.UserCloudDiskMapper;
import cn.iocoder.yudao.module.infra.service.clouddisk.UserCloudDiskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户云盘服务实现类
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class UserCloudDiskServiceImpl implements UserCloudDiskService {

    @Resource
    private UserCloudDiskMapper userCloudDiskMapper;
    
    @Resource
    private DeduplicationFileApi deduplicationFileApi;

    @Override
    @Transactional
    public Long createCloudDiskFile(Long userId, AppUserCloudDiskCreateReqVO createReq) {
        // 获取文件信息
        DeduplicationFileRespDTO fileInfo = deduplicationFileApi.getFileInfo(createReq.getFileId());
        if (fileInfo == null) {
            throw new ServiceException(404, "文件不存在");
        }
        
        // 检查文件名是否重复
        UserCloudDiskDO existingFile = userCloudDiskMapper.selectByUserIdAndFilePath(userId, createReq.getFilePath());
        if (existingFile != null) {
            throw new ServiceException(400, "文件名已存在");
        }
        
        // 创建云盘记录
        UserCloudDiskDO cloudDisk = UserCloudDiskDO.builder()
                .userId(userId)
                .fileId(createReq.getFileId())
                .fileName(createReq.getFileName())
                .fileSize(createReq.getFileSize())
                .fileType(createReq.getFileType())
                .filePath(createReq.getFilePath())
                .parentId(createReq.getParentId())
                .isFolder(false)
                .isFavorite(false)
                .downloadCount(0)
                .viewCount(0)
                .build();
        
        userCloudDiskMapper.insert(cloudDisk);
        
        log.info("[createCloudDiskFile][创建云盘文件成功] userId: {}, fileId: {}, cloudDiskId: {}", 
                userId, createReq.getFileId(), cloudDisk.getId());
        
        return cloudDisk.getId();
    }

    @Override
    @Transactional
    public Long createFolder(Long userId, AppUserCloudDiskCreateFolderReqVO createReq) {
        // 检查文件夹名是否重复
        String folderPath = generateFolderPath(userId, createReq.getParentId(), createReq.getFolderName());
        UserCloudDiskDO existingFolder = userCloudDiskMapper.selectByUserIdAndFilePath(userId, folderPath);
        if (existingFolder != null) {
            throw new ServiceException(400, "文件夹名已存在");
        }
        
        // 创建文件夹记录
        UserCloudDiskDO folder = UserCloudDiskDO.builder()
                .userId(userId)
                .fileId(null)
                .fileName(createReq.getFolderName())
                .fileSize(0L)
                .fileType("folder")
                .filePath(folderPath)
                .parentId(createReq.getParentId())
                .isFolder(true)
                .isFavorite(false)
                .downloadCount(0)
                .viewCount(0)
                .build();
        
        userCloudDiskMapper.insert(folder);
        
        log.info("[createFolder][创建文件夹成功] userId: {}, folderName: {}, folderId: {}", 
                userId, createReq.getFolderName(), folder.getId());
        
        return folder.getId();
    }

    @Override
    public UserCloudDiskDO getCloudDiskFile(Long id) {
        return userCloudDiskMapper.selectById(id);
    }

    @Override
    public List<UserCloudDiskDO> getFileList(Long userId, Long parentId) {
        return userCloudDiskMapper.selectByUserIdAndParentId(userId, parentId);
    }

    @Override
    public PageResult<UserCloudDiskDO> getCloudDiskFilePage(AppUserCloudDiskPageReqVO reqVO) {
        return userCloudDiskMapper.selectPage(reqVO.getUserId(), reqVO.getParentId(), 
                reqVO.getPageNo(), reqVO.getPageSize());
    }

    @Override
    @Transactional
    public void updateCloudDiskFile(Long userId, AppUserCloudDiskUpdateReqVO updateReq) {
        UserCloudDiskDO cloudDisk = userCloudDiskMapper.selectById(updateReq.getId());
        if (cloudDisk == null || !cloudDisk.getUserId().equals(userId)) {
            throw new ServiceException(404, "文件不存在或无权限");
        }
        
        UserCloudDiskDO updateObj = new UserCloudDiskDO();
        updateObj.setId(updateReq.getId());
        
        if (StrUtil.isNotBlank(updateReq.getFileName())) {
            updateObj.setFileName(updateReq.getFileName());
            // 更新文件路径
            String newPath = generateFilePath(userId, updateReq.getParentId() != null ? updateReq.getParentId() : cloudDisk.getParentId(), 
                    updateReq.getFileName());
            updateObj.setFilePath(newPath);
        }
        
        if (updateReq.getParentId() != null) {
            updateObj.setParentId(updateReq.getParentId());
            // 更新文件路径
            String newPath = generateFilePath(userId, updateReq.getParentId(), 
                    updateReq.getFileName() != null ? updateReq.getFileName() : cloudDisk.getFileName());
            updateObj.setFilePath(newPath);
        }
        
        userCloudDiskMapper.updateById(updateObj);
        
        log.info("[updateCloudDiskFile][更新云盘文件成功] userId: {}, cloudDiskId: {}", userId, updateReq.getId());
    }

    @Override
    @Transactional
    public void deleteCloudDiskFile(Long userId, Long id) {
        UserCloudDiskDO cloudDisk = userCloudDiskMapper.selectById(id);
        if (cloudDisk == null || !cloudDisk.getUserId().equals(userId)) {
            throw new ServiceException(404, "文件不存在或无权限");
        }
        
        // 如果是文件夹，检查是否为空
        if (cloudDisk.getIsFolder()) {
            List<UserCloudDiskDO> children = userCloudDiskMapper.selectByParentId(id);
            if (!children.isEmpty()) {
                throw new ServiceException(400, "文件夹不为空，无法删除");
            }
        }
        
        // 删除云盘记录
        userCloudDiskMapper.deleteById(id);
        
        // 如果是文件，减少文件引用计数
        if (!cloudDisk.getIsFolder() && cloudDisk.getFileId() != null) {
            deduplicationFileApi.deleteFile(cloudDisk.getFileId());
        }
        
        log.info("[deleteCloudDiskFile][删除云盘文件成功] userId: {}, cloudDiskId: {}", userId, id);
    }

    @Override
    @Transactional
    public Integer batchDeleteCloudDiskFiles(Long userId, List<Long> ids) {
        int deletedCount = 0;
        for (Long id : ids) {
            try {
                deleteCloudDiskFile(userId, id);
                deletedCount++;
            } catch (Exception e) {
                log.error("[batchDeleteCloudDiskFiles][删除文件失败] userId: {}, cloudDiskId: {}", userId, id, e);
            }
        }
        return deletedCount;
    }

    @Override
    @Transactional
    public void toggleFavorite(Long userId, Long id) {
        UserCloudDiskDO cloudDisk = userCloudDiskMapper.selectById(id);
        if (cloudDisk == null || !cloudDisk.getUserId().equals(userId)) {
            throw new ServiceException(404, "文件不存在或无权限");
        }
        
        UserCloudDiskDO updateObj = new UserCloudDiskDO();
        updateObj.setId(id);
        updateObj.setIsFavorite(!cloudDisk.getIsFavorite());
        
        userCloudDiskMapper.updateById(updateObj);
        
        log.info("[toggleFavorite][切换收藏状态成功] userId: {}, cloudDiskId: {}, isFavorite: {}", 
                userId, id, updateObj.getIsFavorite());
    }

    @Override
    public List<UserCloudDiskDO> getFavoriteFiles(Long userId) {
        return userCloudDiskMapper.selectFavoritesByUserId(userId);
    }

    @Override
    public List<UserCloudDiskDO> searchFiles(Long userId, String keyword, String fileType) {
        return userCloudDiskMapper.searchFiles(userId, keyword, fileType);
    }

    @Override
    public Map<String, Object> getCloudDiskStats(Long userId) {
        Long totalFiles = userCloudDiskMapper.countFilesByUserId(userId);
        Long totalSize = userCloudDiskMapper.sumFileSizeByUserId(userId);
        Long totalFolders = userCloudDiskMapper.countFoldersByUserId(userId);
        
        Map<String, Object> stats = new HashMap<>();
        stats.put("totalFiles", totalFiles);
        stats.put("totalSize", totalSize);
        stats.put("totalFolders", totalFolders);
        stats.put("totalItems", totalFiles + totalFolders);
        
        return stats;
    }

    @Override
    @Transactional
    public String shareFile(Long userId, Long id, AppUserCloudDiskShareReqVO shareReq) {
        UserCloudDiskDO cloudDisk = userCloudDiskMapper.selectById(id);
        if (cloudDisk == null || !cloudDisk.getUserId().equals(userId)) {
            throw new ServiceException(404, "文件不存在或无权限");
        }
        
        // 生成分享码
        String shareCode = IdUtil.simpleUUID();
        LocalDateTime expireTime = LocalDateTime.now().plusDays(shareReq.getExpireDays());
        
        // 更新分享信息
        UserCloudDiskDO updateObj = new UserCloudDiskDO();
        updateObj.setId(id);
        updateObj.setShareCode(shareCode);
        updateObj.setShareExpireTime(expireTime);
        
        userCloudDiskMapper.updateById(updateObj);
        
        log.info("[shareFile][分享文件成功] userId: {}, cloudDiskId: {}, shareCode: {}", userId, id, shareCode);
        
        return shareCode;
    }

    @Override
    public UserCloudDiskDO getSharedFile(String shareCode) {
        UserCloudDiskDO cloudDisk = userCloudDiskMapper.selectByShareCode(shareCode);
        if (cloudDisk == null) {
            return null;
        }
        
        // 检查分享是否过期
        if (cloudDisk.getShareExpireTime() != null && cloudDisk.getShareExpireTime().isBefore(LocalDateTime.now())) {
            return null;
        }
        
        // 增加查看次数
        userCloudDiskMapper.incrementViewCount(cloudDisk.getId());
        
        return cloudDisk;
    }

    // 私有方法
    
    private String generateFolderPath(Long userId, Long parentId, String folderName) {
        return String.format("/cloud-disk/user-%d/parent-%d/%s/", userId, parentId, folderName);
    }
    
    private String generateFilePath(Long userId, Long parentId, String fileName) {
        return String.format("/cloud-disk/user-%d/parent-%d/%s", userId, parentId, fileName);
    }

}
